import { createContext, useContext, useEffect } from 'react'
import { createStore, StateCreator, useStore } from 'zustand'
import { noop, pick } from 'lodash'

import { createPopupSlot } from '@/services/popupSlot'
import { IState, IValue } from './interface'

export const popupSlot = createPopupSlot()

export const createInitState = (): { [P in keyof Required<IState>]: IState[P] } => {
  return {
    xxx: 0,
  }
}

export const createInitValue: StateCreator<IValue> = (set, get, { subscribe }): IValue => {
  const initState = createInitState()
  const stateKeys = Object.keys(initState)

  return {
    ...initState,
    yyy: false,
    zzz: noop,
    subscribe,
    getValue: get,
    setState: state => set(pick(typeof state === 'function' ? state(get()) : state, stateKeys)),
  }
}

export const Ctx = createContext(
  Object.assign(
    createStore<IValue>((...args) => ({
      ...createInitValue(...args),
      subscribe: () => noop,
      setState: noop,
    })),
    { $isDefault: true } as { $isDefault?: true },
  ),
)

export const useSelector = <T>(selector: (value: IValue) => T): T => {
  const store = useContext(Ctx)
  useEffect(() => {
    if (process.env.NODE_ENV === 'development') {
      if (store.$isDefault) console.error('useSelector 需要在对应的上下文中调用')
    }
  }, [store])

  return useStore(store, selector)
}
